package com.leesche.netdoll.communication.event;

import java.util.HashMap;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.leesche.framework.core.concurrent.parallel.EventProcessorGroup;
import com.leesche.netdoll.communication.processor.GameStatusProcessor;
import com.leesche.netdoll.communication.protocol.CommandMessage;
import com.leesche.netdoll.communication.protocol.StartCommandMessage;
import com.leesche.netdoll.communication.protocol.StatusMessage;

public class MessageEventDispatcher {

	private static final Logger logger = LogManager.getLogger(MessageEventDispatcher.class);

	private volatile static MessageEventDispatcher instance;

	private final Map<String, EventProcessorGroup> groups = new HashMap<>();

	private MessageEventDispatcher() {
		final GameStatusProcessor gs = new GameStatusProcessor();

		final EventProcessorGroup commandGroup = new EventProcessorGroup();
		commandGroup.addLast(gs);

		final EventProcessorGroup startCommandGroup = new EventProcessorGroup();
		startCommandGroup.addLast(gs);

		final EventProcessorGroup statusGroup = new EventProcessorGroup();
		statusGroup.addLast(gs);

		final EventProcessorGroup sessionGroup = new EventProcessorGroup();
		sessionGroup.addLast(gs);

		groups.put(CommandMessage.class.getName(), commandGroup);
		groups.put(StartCommandMessage.class.getName(), startCommandGroup);
		groups.put(StatusMessage.class.getName(), statusGroup);
		groups.put(SessionChangedEvent.class.getName(), sessionGroup);
	}

	public static MessageEventDispatcher dispatcher() {
		if (instance == null) {
			synchronized (MessageEventDispatcher.class) {
				if (instance == null)
					instance = new MessageEventDispatcher();
			}
		}
		return instance;
	}

	public void dispatch(MessageEvent event) {
		if (event == null || (!groups.containsKey(event.getClass().getName()))) {
			logger.error("Unsupport Event {}", event);
			return;
		}

		groups.get(event.getClass().getName()).process(event);
	}
}
